﻿using System;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using FRL.DebtChased.Repository;
using FRL.DebtChased.RichContentService;

namespace FRL.DebtChased.Silverlight
{

	/// <summary>
	/// Declaration of CachedDataBase class
	/// </summary>
	public class CachedDataBase
	{

		/////////////////////////////////////////////////////////////
		// Nested classes

		public class ReusableStrings
		{

			/////////////////////////////////////////////////////////
			// Attributes

			private string m_strCategory;
			public string Category
			{
				get { return m_strCategory; }
			}

			private ObservableCollection<string> m_strings;
			public ObservableCollection<string> Strings
			{
				get { return m_strings; }
			}

			/////////////////////////////////////////////////////////
			// Construction

			public ReusableStrings(string strCategory, ObservableCollection<string> strings)
			{

				// Initialize member variables
				m_strCategory = strCategory;
				m_strings = strings;

			}

		}

		/////////////////////////////////////////////////////////////
		// Events

		public event EventHandler<ReusableStringChangeEventArg> ReusableStringChange;

		/////////////////////////////////////////////////////////////
		// Attributes

		protected static CachedDataBase m_SingletonBase;
		public static CachedDataBase SingletonBase
		{
			get { return m_SingletonBase; }
		}

		protected Dictionary<string, string> m_dictCountries = null;
		public Dictionary<string, string> CountryMap
		{
			get { return m_dictCountries; }
		}

		protected ObservableCollection<string> m_CountryNames = null;
		public ObservableCollection<string> CountryNames
		{
			get { return m_CountryNames; }
		}

		private List<ReusableStrings> m_reusableStringsList = new List<ReusableStrings>();

		private string m_strAddReusableString_Category;
		private string m_strAddReusableString_Value;
		private bool m_bAddReusableString_Add;

		public ObservableCollection<string> ContactCounties
		{
			get { return _safeFindStringListByCategory(Definitions.ReusableString_ContactCounties); }
		}

		public ObservableCollection<string> ContactTitles
		{
			get { return _safeFindStringListByCategory(Definitions.ReusableString_ContactTitles); }
		}

		public ObservableCollection<string> ContactPositions
		{
			get { return _safeFindStringListByCategory(Definitions.ReusableString_ContactPositions); }
		}

		public ObservableCollection<string> BankNames
		{
			get { return _safeFindStringListByCategory(Definitions.ReusableString_BankNames); }
		}

		private Definitions.eRoles m_roles;
		public Definitions.eRoles Roles
		{
			get { return m_roles; }
		}

		/////////////////////////////////////////////////////////////
		// Construction

		protected CachedDataBase()
		{
#if DEBUG
			Debug.Assert(m_SingletonBase == null);
#endif // #if DEBUG
			
			// Update the single reference
			m_SingletonBase = this;

		}

		/////////////////////////////////////////////////////////////
		#region Operations

		protected void AddIncoming(
			int iCurrentUserRoles,
			Dictionary<string, string> countryMap,
			ObservableCollection<string> contactPositions,
			ObservableCollection<string> contactTitles,
			ObservableCollection<string> contactCounties,
			ObservableCollection<string> bankNames
		)
		{

			// Update member variables
			this.m_roles = (Definitions.eRoles)iCurrentUserRoles;

			// Create dictionary of countries
			this.m_dictCountries = countryMap;
			m_CountryNames = new ObservableCollection<string>();
			foreach (var di in this.m_dictCountries)
				m_CountryNames.Add(di.Value);

			// Update reusable strings
			this.AddReusableStrings(Definitions.ReusableString_ContactPositions, contactPositions);
			this.AddReusableStrings(Definitions.ReusableString_ContactTitles, contactTitles);
			this.AddReusableStrings(Definitions.ReusableString_ContactCounties, contactCounties);
			this.AddReusableStrings(Definitions.ReusableString_BankNames, bankNames);

		}

		#endregion Operations

		/////////////////////////////////////////////////////////////
		#region Operations - Reusable Strings

		private ReusableStrings _findByCategory(string strCategory)
		{

			// Declare return variable
			ReusableStrings Ftmp = null;

			// Loop through list
			foreach (ReusableStrings rs in m_reusableStringsList)
			{

				// Compare categories
				if (rs.Category == strCategory)
				{

					// Update return variable and break
					Ftmp = rs;
					break;

				}

			}

			// Return variable
			return Ftmp;

		}

		protected ObservableCollection<string> _safeFindStringListByCategory(string strCategory)
		{

			// Declare return variable
			ObservableCollection<string> Ftmp = null;

			// Find reusable
			ReusableStrings rs = _findByCategory(strCategory);
			if (rs != null)
				Ftmp = rs.Strings;

			// Return variable
			return Ftmp;

		}

		public void ResuableStringAdded_Pending(string strCategory, string strValue, bool bAdd)
		{

			// Retain values
			m_strAddReusableString_Category = strCategory;
			m_strAddReusableString_Value = strValue;
			m_bAddReusableString_Add = bAdd;

		}

		public void ResuableStringAdded_Complete()
		{
#if DEBUG
			Debug.Assert(m_strAddReusableString_Category != null);
			Debug.Assert(m_strAddReusableString_Value != null);
#endif // #if DEBUG

			// Find the reusable strings
			ReusableStrings rs = _findByCategory(m_strAddReusableString_Category);
			if (rs == null)
			{
#if DEBUG
				Debug.Assert(false);
#endif // #if DEBUG
				return;
			}

			// If adding string...
			if (m_bAddReusableString_Add)
			{
				if (!rs.Strings.Contains(m_strAddReusableString_Value))
					rs.Strings.Add(m_strAddReusableString_Value);
			}
			else
				rs.Strings.Remove(m_strAddReusableString_Value);

			// Send an event
			if (ReusableStringChange != null)
				ReusableStringChange(null, new ReusableStringChangeEventArg(m_strAddReusableString_Category));

		}

		protected void AddReusableStrings( string strCategory, ObservableCollection<string> strings )
		{
#if DEBUG
			Debug.Assert(_findByCategory(strCategory) == null);
#endif // #if DEBUG

			// Add a new rs object
			m_reusableStringsList.Add( new ReusableStrings(strCategory, strings) );

		}

		#endregion Operations - Reusable Strings

		/////////////////////////////////////////////////////////////
		// Operations - Dummy Data

#if USEFAKEDATA
		protected static Dictionary<string, string> GetDummyCountryMap()
		{

			// Load the dictionary
			Dictionary<string, string> Ftmp = new Dictionary<string, string>();
			Ftmp.Add("UK", "United Kingdom");
			Ftmp.Add("RS", "Russia");
			Ftmp.Add("FR", "France");
			return Ftmp;

		}
#endif // #if USEFAKEDATA

#if USEFAKEDATA
		protected static ObservableCollection<string> GetDummyContactCounties()
		{

			// Load the re-usable strings
			ObservableCollection<string> Ftmp = new ObservableCollection<string>();
			Ftmp.Add("Berks");
			Ftmp.Add("Surrey");
			Ftmp.Add("Kent");
			return Ftmp;

		}

#endif // #if USEFAKEDATA

#if USEFAKEDATA
		protected static ObservableCollection<string> GetDummyContactTitles()
		{

			// Load the re-usable strings
			ObservableCollection<string> Ftmp = new ObservableCollection<string>();
			Ftmp.Add("Mr.");
			Ftmp.Add("Mrs.");
			Ftmp.Add("Dr.");
			return Ftmp;

		}

#endif // #if USEFAKEDATA

#if USEFAKEDATA
		protected static ObservableCollection<string> GetDummyContactPositions()
		{

			// Load the re-usable strings
			ObservableCollection<string> Ftmp = new ObservableCollection<string>();
			Ftmp.Add("CEO");
			Ftmp.Add("Director");
			return Ftmp;

		}
#endif // #if USEFAKEDATA

#if USEFAKEDATA
		protected static ClientTransport GetDummyClientTransport()
		{

			// Declare return variable
			ClientTransport Ftmp = new ClientTransport();
			Ftmp.ClientInstructionBatchList = new ObservableCollection<ClientInstructionBatchTransport>();
			Ftmp.Contacts = new System.Collections.ObjectModel.ObservableCollection<ContactTransport>();

			// Set agent details
			Ftmp.ClientId = 1;
			Ftmp.Name = "Colin Client";
			Ftmp.Website = "www.broccoliproducts.com";
			Ftmp.Notes = "Bla bla bla";

			// Add instruction batch list
			Ftmp.ClientInstructionBatchList.Add(new ClientInstructionBatchTransport() { ClientInstructionBatchId = 1, Name = "BatchA", InUse = false });
			Ftmp.ClientInstructionBatchList.Add(new ClientInstructionBatchTransport() { ClientInstructionBatchId = 2, Name = "BatchB", InUse = true });
			Ftmp.ClientInstructionBatchList.Add(new ClientInstructionBatchTransport() { ClientInstructionBatchId = 3, Name = "BatchC", InUse = true });

			// Add contact
			ContactTransport newContact = new ContactTransport();
			newContact.AddressList = new System.Collections.ObjectModel.ObservableCollection<ContactAddressTransport>();
			newContact.PointList = new System.Collections.ObjectModel.ObservableCollection<ContactPointTransport>();
			newContact.ContactId = 1;
			newContact.Title = "Mr.";
			newContact.FirstName = "Toby";
			newContact.Initials = "X";
			newContact.Surname = "Stephens";
			newContact.Position = "CEO";
			newContact.Abbr = "Toz";
			newContact.AddressList.Add(new ContactAddressTransport()
			{
				AddressLineA = "Unit 45",
				AddressLineB = "Eastway Trading Estate",
				City = "Slough",
				County = "Berkss",
				CountryCode = "UK"
			});
			newContact.AddressList.Add(new ContactAddressTransport()
			{
				AddressLineA = "1 Sylverns Court",
				AddressLineB = "Warfield",
				City = "Bracknell",
				County = "Berks",
				Postcode = "RG42 3SL",
				CountryCode = "UK"
			});
			newContact.PointList.Add(
				new ContactPointTransport() { ContactPointType = (int)Definitions.eContactPointType.Phone, Address = "01344 485 185" }
			);
			newContact.PointList.Add(
				new ContactPointTransport() { ContactPointType = (int)Definitions.eContactPointType.Mobile, Address = "07956 666362" }
			);
			newContact.PointList.Add(
				new ContactPointTransport() { ContactPointType = (int)Definitions.eContactPointType.Email, Address = "richardpsalmon@hotmail.com" }
			);
			Ftmp.Contacts.Add(newContact);

			// Return variable
			return Ftmp;

		}
#endif // #if USEFAKEDATA

#if USEFAKEDATA
		protected static Dictionary<int, string> GetDummyTradingStyleMap()
		{

			// Load a map
			Dictionary<int, string> Ftmp = new Dictionary<int, string>();
			Ftmp.Add(0, "Not Set");
			Ftmp.Add(1, "Limited Company");
			Ftmp.Add(2, "PLC");
			return Ftmp;

		}
#endif // #if USEFAKEDATA

	}

}
